home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr40
/
x1j4_src.zip
/
TNL7C.C
< prev
next >
Wrap
Text File
|
1995-01-08
|
23KB
|
690 lines
/*****************************************************************************/
/* */
/* */
/* ***** ***** */
/* ***** ***** */
/* ***** ***** */
/* ***** ***** */
/* *************** *************** */
/* ***************** ***************** */
/* *************** *************** */
/* ***** ***** TheNet */
/* ***** ***** Portable. Compatible. */
/* ***** ***** Public Domain */
/* ***** ***** NORD><LINK */
/* */
/* This software is public domain ONLY for non commercial use */
/* */
/* */
/*****************************************************************************/
/* Level 7C, Hostinterface */
/* Version 1.01 */
/* Hans Georg Giese, DF2AU, Hinter dem Berge 5, 3300 Braunschweig */
/* 02-APR-88 */
/* Modified April 1991 G8KBB - use of register keyword
* - use all.h header file
* - host commands for KISS & HOST optional compile
* - optinally remove unneeded esc commands
* - replace many simple operations by assembler
*/
/*
* September 1993 - released as TheNet X-1J
*/
#include "all.h"
#include "tntyp.h" /* Definition der Typen */
#include "tnl7ce.h" /* externe Definitionen */
/*---------------------------------------------------------------------------*/
VOID hosini() /* Hostinterface initialisieren */
{
hstusr = &hstubl[0]; /* Pointer auf Kontrollblock setzen */
hstusr->conflg = /* Host ist nicht connected */
hstusr->disflg = /* kein Disconnect nach Info-senden */
hstusr->inlin = /* keine Zeilen von Eingabe da */
hstusr->outlin = /* keine Zeilen fuer Ausgabe da */
blixfl = /* Host darf nicht connected werden */
#ifndef MODIFIED
hostco = /* Host darf nicht connected werden */
#endif
blicnt = 0; /* Eingabezeile ist leer */
inithd(&hstusr->inbuf); /* Listenkopf Eingabepuffer initialisieren */
inithd(&hstusr->outbuf); /* Listenkopf Ausgabepuffer initialisieren */
magicn = MAGIC; /* Flag fuer Warmstart setzen */
}
/*---------------------------------------------------------------------------*/
VOID hostsv() /* Hostinterface Service */
{ /* regelmaessig von MAIN aufgerufen */
register char zeichen; /* Scratch fuer Eingabehandling */
register mhtyp *mbuff; /* Messagebuffer */
hstusr = &hstubl[0]; /* Pointer auf Kontrollblock setzen */
#ifdef HOSTMODE
if( hstmod && ishost() )
hstmodsv();
#endif
hstsen(0); /* falls Info vorhanden: senden, wenn Platz */
if (((hstusr->disflg & 0x80) != 0) /* Disconnect gefordert? */
&& (hstusr->outlin == 0)) /* und Info gesendet? */
hstdis(); /* dann disconnecten */
if (! blicnt && ! blixfl) { /* Zeile leer und kein X-OFF gekommen? */
/* dann Ausgabe versuchen */
while (! ishput() && hstusr->outlin != 0) /* SIO frei und was da? */
{
mbuff = (mhtyp *) unlink(hstusr->outbuf.lnext); /*Buffer aus Kette */
hstusr->outlin -=1; /* eine Zeile weniger */
while (mbuff->getcnt < mbuff->putcnt) /* Info ausgeben */
{
zeichen = (getchr(mbuff) &0x7f); /* Zeichen holen */
if (zeichen == 0x7f) zeichen = 0x08; /* RUBOUT wird Backspace */
if ((zeichen >= ' ') || (zeichen == 0x0a) ||
(zeichen == 0x07) || (zeichen == 0x09))
hputc(zeichen); /* druckbare Zeichen ausgeben*/
else
{
if (zeichen == 0x0d)
{
hputc(zeichen); /* CR wird CR-LF */
hputc(0x0a);
}
else /* andere Kontrollzeichen */
{
hputc('^'); /* mit Prefix */
hputc(zeichen + '@');
}
}
}
dealmb(mbuff); /* Buffer freigeben */
}
}
if (ishget() /* == 1 */) { /* Zeichen von Eingabe bereit? */
zeichen = hgetc() & 0x7f; /* dann holen, ohne Parity */
if (! blicnt) /* erstes Zeichen der Zeile? */
blipoi = bline; /* Pointer auf Anfang setzen */
switch(zeichen) {
/*==============================*/
case 0x0d: /* Ende der Zeile */
hputc(zeichen); /* Echo fuer <CR> */
hputc(0x0a); /* <LF> anhaengen */
blipoi = bline; /* Pointer auf Anfang fuer Verarbeitung */
if ((blicnt != 0) /* etwas eingegeben? */
&& (*blipoi == DEFESC) /* und erstes Zeichen = <ESC>? dann Befehl */
#ifdef HOSTMODE
&& ( hstmod == 0 || ( hstmod && (hststs == 0) ) ) )
#else
)
#endif
{
++blipoi; /* erstes Zeichen ist verarbeitet */
--blicnt; /* Zahl der Zeichen -1 */
hstcmd(); /* Befehl verarbeiten */
}
else /* Zeile kein Befehl: */
{
if ((hstusr->conflg != 0) /* Host connected? */
&& ((nmbfre > 64) /* noch Platz im Speicher? */
&& ((hstusr->disflg & 0x80) == 0))) /* kein DISC eingeleitet? */
{
mbuff = (mhtyp *) allocb(); /* Buffer holen */
while (blicnt--) /* Zeile uebertragen */
putchr(*blipoi++, mbuff);
putchr('\15', mbuff);/* <CR> anhaengen */
rwndmb(mbuff); /* alle Bufferpointer wieder auf 0 */
relink(mbuff, hstusr->inbuf.lprev); /* in Kette haengen */
++hstusr->inlin; /* Zahl der Zeilen +1 */
}
}
blicnt = 0;
break;
/*==============================*/
case 0x08: /* Backspace */
case 0x7f: /* Rubout */
if (blicnt != 0) bliloe(); /* Zeichen loeschen - wenn vorhanden */
break;
/*==============================*/
case 0x15: /* ctl-u = Zeile loeschen */
case 0x18: /* ctl-x = Zeile loeschen */
while (blicnt != 0) bliloe(); /* alles killen */
break;
/*==============================*/
case 0x11: /* X-ON */
blixfl = FALSE;
break;
/*==============================*/
case 0x13: /* X-OFF */
blixfl = TRUE;
break;
/*==============================*/
default: /* sonstiges Zeichen */
if (blicnt < BLINLEN) { /* noch Platz in der Zeile? */
blieco(zeichen); /* Echo ausgeben */
*blipoi++ = zeichen; /* Zeichen in Buffer */
++blicnt; /* Zeilenlaenge zaehlen */
}
else hputc(0x07); /* kein Platz: meckern! */
break;
}
}
}
/*---------------------------------------------------------------------------*/
VOID hostim() /* Host Timerservice */
{ /* Aufruf jede Sekunde von MAIN */
hstusr = &hstubl[0]; /* Pointer auf Userblock setzen */
if (hstusr->conflg != 0) /* wenn Host connected */
{
if ((hstusr->noact2 != 0) /* und Timeout noch nicht 0 */
&& (--hstusr->noact2 == 0)) /* Timeout runterzaehlen */
hstdis(); /* bei 0 abwerfen */
}
#ifdef HOSTMODE
if( hstmod && (hststs == 3) && ishost() )
if( --hotout == 0 )
hststs = 0;
#endif
}
/*---------------------------------------------------------------------------*/
VOID hstreq() /* Connect Request an Host */
{
#ifdef HOSTMODE
if( hstmod && ishost() )
{
if(
#ifndef MODIFIED
hostco == 1 &&
#endif
#ifdef PK96
hststs == 0 && ( CNTLB0 & (1<<5) ) )
#else
hststs == 0 && ( SIBRR0 & (1<<5) ) )
#endif
{
raisedcd();
hststs = 1;
hstcon();
}
else
putmsg("Host faulty or unavailable.");
}
else
{
#endif
#ifdef MODIFIED
hstcon();
#else
if (hostco == 1) hstcon(); /* ausfuehren, wenn erlaubt */
else { /* sonst anklopfen */
bstrng("\015\012CONNECT REQUEST fm ");
bcalou(hstusr->call); /* Call melden */
bbel(); /* bimmeln */
l2tol7(3, hstusr, 0); /* mit DM nach unten melden */
}
#endif
}
#ifdef HOSTMODE
}
#endif
/*---------------------------------------------------------------------------*/
VOID hstout() /* Host Interface Timeout */
{
dealml(& hstusr->inbuf); /* eingegebene Zeilen loeschen */
hstusr->inlin = 0;
hstusr->disflg |= 0x80; /* Abwurf verlangen */
}
/*---------------------------------------------------------------------------*/
BOOLEAN hstrec(conflg, ublk) /* Info fuer Host zeigen */
register mhtyp *ublk; /* User Kontroll Block */
BOOLEAN conflg; /* Congestion Flag */
{
register hustyp *cblk; /* lokaler Kontrollblock */
cblk = (hustyp *) ublk->l2lnk; /* auf Host-Kontollblock */
if ((conflg /*== 1*/) || (cblk->outlin < conctl)) /* noch Platz ? */
{
relink(unlink(ublk), cblk->outbuf.lprev); /* Buffer umhaengen */
++cblk->outlin; /* eine Zeile mehr */
cblk->noact2 = ininat; /* Timeout neu setzen */
return (TRUE); /* OK, Info ist auf dem Weg */
}
else return (FALSE); /* Fehler, hat nicht funktioniert */
}
/*---------------------------------------------------------------------------*/
VOID blieco(zeichen) /* Echo fuer Hostterminal */
register char zeichen;
{
if (blicnt == 0 && zeichen == DEFESC &&
( hstmod==0 || (hstmod && (hststs == 0) ))) /* erstes Zeichen und <ESC>? */
bstrng("* "); /* dann * als Echo */
else { /* alle anderen Zeichen */
if (zeichen >= ' ' || zeichen == 0x07) /* druckbar oder BELL? */
hputc(zeichen); /* dann Echo */
else { /* sonstige Kontrolzeichen */
hputc('^'); /* Prefix */
hputc(zeichen + '@'); /* Zeichen - druckbar gemacht */
}
}
}
/*---------------------------------------------------------------------------*/
VOID bliloe() /* 1 Zeichen am Hostterminal loeschen */
{
register char zeichen; /* Scratch */
if ((zeichen = *(--blipoi)) != 0x07) { /* Sonderfall BELL */
bputbs(); /* Zeichen loeschen */
if (zeichen < ' ') bputbs();/* Controlzeichen: Prefix + Zeichen loeschen */
}
else hputc(zeichen); /* BELL wird wiederholt */
--blicnt; /* Zeilenlaenge -1 */
}
/*---------------------------------------------------------------------------*/
VOID hstcmd() /* Befehl an Hostinterface ausfuehren */
{
register char *paspoi; /* Pointer in Passwort (<ESC>-P) */
register char zeichen; /* Scratch */
register unsigned arg; /* Argument des Befehls */
unsigned cnt; /* Scratch */
skipsp(&blicnt, &blipoi); /* Leerzeichen am Anfang uebergehen */
if (blicnt != 0) { /* ueberhaupt was da? */
zeichen = upcase(*blipoi++);/* Befehl - erstes Zeichen - holen */
--blicnt; /* ein Zeichen ist verbraucht */
skipsp(&blicnt, &blipoi); /* Rest bis zum Argument ueberlesen */
switch(zeichen) {
/*==============================*/
case 'C': /* Host an TNC connecten */
if (hstusr->conflg == 0 && hstmod == 0 )
{ /* schon connected? Dann uebergehen */
cpyid(hstusr->call, myid); /* Host ist am TNC */
hstcon(); /* an alle melden */
}
break;
/*==============================*/
case 'D': /* Host vom TNC disconnecten */
if (hstusr->conflg != 0 && hstmod == 0 )
{ /* schon disconnected? Dann uebergehen */
hstsen(1); /* an alle melden, sofort alles senden */
hstdis(); /* Interface trennen, melden */
}
break;
/*==============================*/
case 'P': /* Passwort zeigen-eingeben */
if (blicnt == 0) { /* ohne Argument = zeigen */
bpromp(); /* neue Zeile, * */
paspoi = paswrd; /* auf Anfang des Passwortes */
for (cnt = 0; cnt < paswle; ++cnt)
bchout(*paspoi++); /* Passwort ausgeben */
bende(); /* und * am Ende */
}
else { /* neues Passwort setzen */
paspoi = paswrd; /* auf Anfang Passwort */
paswle = /* Laenge = 0 */
cnt = 0; /* eingegebene Zeichen = 0 */
while (blicnt-- != 0) { /* Rest der Zeile ist Passwort */
if ((zeichen = *blipoi++) != 0x0a) { /* Linefeed ueberlesen */
if ((*paspoi++ = zeichen) != ' ') /* Leerzeichen zaehlen nicht */
++cnt;
++paswle;
if (paswle == 80)
break; /* maximale Laenge erreicht? */
}
}
if (cnt < 5)
paswle = 0; /* Mindestlaenge muss eingehalten werden */
}
break;
#ifndef MODIFIED
/*==============================*/
case 'T': /* Keyup Delay zeigen-eingeben */
hstparm( &Tpar, 255 );
break;
/*==============================*/
case 'Y': /* Connect zu Host erlaubt j-n */
hstparm( &hostco, 1 );
break;
/*==============================*/
case 'F': /* Full-Duplex j-n */
if (blicnt == 0) /* ohne Argument = zeigen */
bnuout(Dpar);
else /* mit Argument = setzen */
{
if ((arg = nxtnum(&blicnt, &blipoi)) <= 1) /* holen, testen */
{
if ((Dpar == FALSE) && (arg == TRUE))
{ /* Wechsel auf Full */
DIinc(); /* Interrupts aus */
Dpar = TRUE;
pushtx(); /* Sender anwerfen */
decEI(); /* Interrupts an */
}
Dpar = arg; /* ok, merken */
}
else
invcmd(); /* meckern */
}
break;
#ifdef KISSMODE
/*==============================*/
case 'K': /* Kiss or crosslink mode j-n */
hstparm( &crlmod, 3 );
break;
#endif
#ifdef HOSTMODE
/*==============================*/
case 'H': /* Host mode j-n */
hstparm( &hstmod, 1 );
break;
#endif
#endif
/*==============================*/
default : /* ungueltiger Befehl */
invcmd(); /* meckern */
break;
}
}
}
/*--------------------------helper utility to hstcmd()-----------------------*/
#ifdef MODIFIEDANDNEVERDOTHIS
hstparm( variable, limit )
unsigned char *variable;
unsigned limit;
{
register unsigned arg;
if (blicnt == 0) /* ohne Argument = zeigen */
bnuout(*variable);
else
{ /* mit Argument = setzen */
if ((arg = nxtnum(&blicnt, &blipoi)) <= limit) /* holen, testen */
*variable = arg; /* ok, merken */
else
invcmd(); /* meckern */
}
}
#endif
/*---------------------------------------------------------------------------*/
VOID hstcon() /* Host wird connected */
{
bstrng("\015\012CONNECTED to ");
bcalou(hstusr->call); /* Meldung mit Call und Bimmel */
bbel();
l2tol7(1, hstusr, 0); /* nach unten melden: Usrtyp, ctrl-blk, cmd */
hstusr->conflg = 1; /* Connect Flag setzen */
hstusr->noact2 = ininat; /* no-activity-timeout neu setzen */
}
/*---------------------------------------------------------------------------*/
VOID hstdis() /* Host wird disconnected */
{
dealml(& hstusr->inbuf); /* Eingabebuffer freigeben */
dealml(& hstusr->outbuf); /* Ausgabebuffer freigeben */
hstusr->inlin = /* keine Zeile in Eingabe */
hstusr->outlin = 0; /* keine Zeile in Ausgabe */
bstrng("\015\012DISCONNECTED fm ");
bcalou(hstusr->call); /* Meldung mit Call und Bimmel */
bbel();
l2tol7(2, hstusr, 0); /* nach unten melden: Usrtyp, ctrl-blk, cmd */
hstusr->conflg = /* Connect Flag ruecksetzen */
hstusr->disflg = 0; /* Abwurf ausgefuehrt markieren */
#ifdef HOSTMODE
if( hststs == 1 )
hststs = 4;
else if( hststs == 2 )
{
dropdcd();
hststs = 3;
hotout = 20;
}
#endif
}
/*---------------------------------------------------------------------------*/
VOID hstsen(conflg) /* Host Sende Service */
BOOLEAN conflg; /* Congestion Flag, 0=normal, 1=alles sofort */
{
register mhtyp *mbhd; /* Message Buffer Head der Info */
while (hstusr->inlin != 0) /* solange Zeilen vorhanden */
{
mbhd = (mhtyp *) hstusr->inbuf.lnext; /* MBHD aufbauen */
mbhd->l2lnk = (l2ltyp *) hstusr; /* User ist Host */
mbhd->usrtyp = 0; /* Usertyp setzen */
if (! fmlink(conflg, mbhd)) /* Frame senden, Fehler dabei? */
break; /* im Fehlerfalle Abbruch */
hstusr->inlin -=1; /* eine Zeile erledigt */
hstusr->noact2 = ininat; /* no-activity-timeout neu setzen */
}
}
/*---------------------------------------------------------------------------*/
VOID bcalou (call) /* Call auf Crosslink Kanal geben */
char *call;
{
register unsigned z_zahl; /* Anzahl ausgegebener Zeichen */
register char ssid; /* SSID des Calls */
register char zeichen; /* aktuelles Zeichen */
for (z_zahl = 6; z_zahl != 0; --z_zahl)
{
zeichen = *call++;
if (zeichen != ' ') bchout(zeichen);
}
ssid = (*call >> 1) & 0x0f;
if (ssid)
{
hputc('-');
bnumou(ssid);
}
}
/*---------------------------------------------------------------------------*/
VOID bnuout (zahl) /* Zahl auf Crosslink Kanal geben */
int zahl; /* eingerahmt in * * */
{
bpromp(); /* neue Zeile, * */
bnumou(zahl); /* Zahl */
bende(); /* und * am Ende */
}
/*---------------------------------------------------------------------------*/
VOID bnumou (zahl) /* Zahl auf Crosslink Kanal geben */
unsigned zahl;
{
BOOLEAN notnul; /* fuehrende Null j/n */
register unsigned diviso; /* Stellenwert der aktuellen Stelle */
register unsigned ziffer; /* aktuelle Ziffer */
register unsigned numcnt; /* Zahl der ausgegebenen Ziffern */
notnul = FALSE;
diviso = 10000;
for(numcnt = 5; numcnt != 0; --numcnt) {
ziffer = zahl / diviso;
if ((ziffer != 0) || (notnul /*== TRUE*/) || (diviso == 1)) {
hputc (ziffer + '0');
notnul = TRUE;
}
zahl %= diviso;
diviso /= 10;
}
}
#ifdef PORTABLE
/*---------------------------------------------------------------------------*/
VOID bputbs() /* Backspace an Hostterminal */
{
bstrng("\010 \010"); /* Backspace soll destruktiv sein */
}
/*---------------------------------------------------------------------------*/
VOID invcmd() /* ungueltigen Befehl melden */
{
bstrng("* INVALID COMMAND *\007\015\012");
}
/*---------------------------------------------------------------------------*/
VOID bpromp() /* Prompt auf Crosslink Kanal */
{
bstrng("* ");
}
/*---------------------------------------------------------------------------*/
VOID bende() /* Ende Kennung auf Crosslink Kanal */
{
bstrng(" *\015\012");
}
/*---------------------------------------------------------------------------*/
VOID bbel() /* BELL Ausgabe auf Crosslink Kanal */
{
bstrng("\015\012\007");
}
#else
#asm
.z80
public invcmd_, bpromp_, bende_, bbel_, bputbs_
extrn bstrng_
bputbs_: ld hl,bputbs
jr bbelx
invcmd_: ld hl,invcmds
jr bbelx
bpromp_: ld hl,bpromps
jr bbelx
bende_: ld hl,bendes
jr bbelx
bbel_: ld hl,bbels
bbelx: push hl
call bstrng_
pop hl
ret
invcmds: db '* INVALID COMMAND *'
bbels: db 13,10,7,0
bpromps: db '*',' ',0
bendes: db ' ','*',13,10,0
bputbs: db 8,' ',8,0
.8080
#endasm
#endif
/*---------------------------------------------------------------------------*/
VOID bstrng (string) /* String auf Crossllink Kanal geben */
register char *string;
{
while (*string != 0) hputc(*string++);
}
/*---------------------------------------------------------------------------*/
VOID bchout (c) /* Zeichen auf Crosslink Kanal geben */
register char c;
{
if (c >= ' ') hputc(c);
else {
hputc('^');
hputc(c + '@');
}
}
/*---------------------------------------------------------------------------*/
BOOLEAN iswarm () /* Test auf Warmstart */
{
return (magicn == MAGIC); /* RAM noch intakt? dann Warmstart */
}
/*---------------------------------------------------------------------------*/
#ifdef HOSTMODE
VOID hstmodsv()
{
switch( hststs )
{
case 5:
if( hstusr->conflg == 0 )
{
cpyid( hstusr->call, myid );
hstcon();
hststs = 2;
}
else
{
bstrng("\015\013TNC Busy.");
hststs = 3;
}
break;
case 6:
dropdcd();
hststs = 3;
hotout = 20;
break;
case 7:
if( hstusr-> conflg )
{
hstsen( 1 );
hstdis();
}
dropdcd();
hststs = 0;
}
}
#endif
/*--- Ende Level 7c ---------------------------------------------------------*/